"""
FileName：data_driver.py
Description：
Author：gaojiahui
Time：2025/8/24 16:52
Website：https://gitee.com/gao-jiahui
"""
import inspect
from typing import List, Dict, Any, Callable

from config.settings import settings
from core.logger import logger
from test_data.data_validator import DataValidator
from test_data.excel_loader import ExcelDataLoader
from test_data.json_loader import JSONDataLoader
from test_data.yaml_loader import YAMLDataLoader
from utils.data_util import generate_phone_number, generate_random_uppercase_string


class DataDriver:
    """数据驱动引擎"""

    def __init__(self):
        self.loader = self._get_data_loader()
        self.validator = DataValidator()

    def _get_data_loader(self):
        """获取数据加载器"""
        format_type = settings.TEST_DATA_FORMAT.lower()

        if format_type == "excel":
            return ExcelDataLoader()
        elif format_type == "json":
            return JSONDataLoader()
        elif format_type == "yaml":
            return YAMLDataLoader()
        else:
            logger.warning(f"不支持的数据格式: {format_type}, 使用默认的Excel格式")
            return ExcelDataLoader()

    def load_test_cases(self, module: str, feature: str) -> List[Dict[str, Any]]:
        """加载测试用例"""
        test_cases = self.loader.get_test_cases(module,feature)

        if not test_cases:
            logger.warning(f"未找到测试用例: {module}/{feature}")
            return []

        # 数据验证
        if settings.DATA_VALIDATION_ENABLED:
            valid_cases = []
            for case in test_cases:
                if self.validator.validate_test_case(case):
                    valid_cases.append(case)
                else:
                    logger.warning(f"测试用例验证失败: {case.get('test_case_id', '未知')}")

            test_cases = valid_cases

        # 动态数据生成
        if settings.DYNAMIC_DATA_ENABLED:
            test_cases = self._generate_dynamic_data(test_cases)

        return test_cases

    def _generate_dynamic_data(self, test_cases: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """生成动态数据"""
        import random
        import time

        dynamic_values = {
            "${timestamp}": str(int(time.time())),
            "${random_int}": str(random.randint(1000, 9999)),
            "${random_string}": generate_random_uppercase_string(8),
            "${random_phone}": generate_phone_number(),
            "${random_email}": f"test{random.randint(1000, 9999)}@example.com"
        }

        processed_cases = []
        for case in test_cases:
            processed_case = self._replace_dynamic_values(case, dynamic_values)
            processed_cases.append(processed_case)

        return processed_cases

    def _replace_dynamic_values(self, data: Any, dynamic_values: Dict[str, str]) -> Any:
        """替换动态值"""
        if isinstance(data, dict):
            return {k: self._replace_dynamic_values(v,dynamic_values) for k, v in data.items()}
        elif isinstance(data, list):
            return [self._replace_dynamic_values(item, dynamic_values) for item in data]
        elif isinstance(data, str):
            for pattern, replacement in dynamic_values.items():
                data = data.replace(pattern, replacement)
            return data
        else:
            return data

    def create_data_driven_test(self, test_function: Callable, module: str, feature: str):
        """创建数据驱动测试"""
        test_cases = self.load_test_cases(module, feature)

        if not test_cases:
            logger.error(f"无法为 {module}/{feature} 创建数据驱动测试: 没有测试用例")
            return None

        # 获取测试函数的参数
        sig = inspect.signature(test_function)
        params = list(sig.parameters.keys())

        # 创建参数化测试
        import pytest

        def create_test_case(test_case):
            def test_wrapper():
                # 准备测试参数
                kwargs = {}
                for param in params:
                    if param in test_case:
                        kwargs[param] = test_case[param]
                    elif param == "test_case_data":
                        kwargs[param] = test_case

                # 执行测试函数
                return test_function(**kwargs)

            return test_wrapper()

        # 为每个测试用例创建测试方法
        test_methods = []
        for i, test_case in enumerate(test_cases):
            test_method = create_test_case(test_case)
            test_method.__name__ = f"test_{feature}_{i:03d}_{test_case.get('test_case_id','')}"
            test_methods.append(test_method)

        return test_methods

    def generate_test_data_template(self, module: str, feature: str, fields: List[Dict[str, Any]]):
        """生成测试数据模板"""
        template_data = []

        # 添加示例测试用例
        example_case = {"test_case_id": f"{feature}_001", "description": f"示例测试用例"}

        for field in fields:
            field_name = field.get("name")
            field_type = field.get("type", "string")
            field_default = field.get("default", "")
            field_required = field.get("required", True)

            if field_required:
                example_case[field_name] = field_default

        template_data.append(example_case)

        # 保存模板
        file_name = f"{feature}_cases.{self.loader.get_file_extension()}"
        file_path = settings.TEST_DATA_TEMPLATE_DIR / file_name

        return self.loader.save_data(str(file_path), template_data)

# 全局数据驱动实例
data_driver = DataDriver()
